package cn.redragon.soa.amqp.handler;


import static cn.redragon.soa.common.constant.RedisCacheKey.RESERVATION_EXPIRED_PREFIX;

import cn.redragon.soa.common.constant.Constants;
import cn.redragon.soa.common.enums.StockActionType;
import cn.redragon.soa.common.service.RedisService;
import cn.redragon.soa.service.StockService;
import java.time.Duration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@RequiredArgsConstructor
public class RedisKeyExpirationListener implements MessageListener {

    private final RedisService redisService;
    private final StockService stockService;

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String expiredKey = message.toString();
        log.info("Received Expired Key: {}", expiredKey);

        if (StringUtils.containsIgnoreCase(expiredKey, RESERVATION_EXPIRED_PREFIX)) {
            String keyHash = DigestUtils.md5Hex(expiredKey);
            if (!redisService.acquireLock(keyHash, keyHash, Duration.ofSeconds(Constants.TtlTime.TTL_30_SEC))) {
                return;
            }
            String[] values = expiredKey.replace(RESERVATION_EXPIRED_PREFIX, StringUtils.EMPTY).split(Constants.Separator.COLON);
            String appCode = values[0];
            String type = values[1];
            String customerId = values[2];
            String orderNumber = values[3];
            //remove reserved stock
            try {
                stockService.cancelStocks(appCode, type, customerId, orderNumber, "SYSTEM", StockActionType.EXPIRE_ORDER);
            } catch (RuntimeException ex) {
                log.error("Cancel reservation with ttl expiration failed: {}", ex);
            }

        }

    }
}
